import json
import re
from django.contrib.auth import login
from django.contrib.auth import logout
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from apps.users.models import User
from apps.users.models import Address



# Create your views here.
# 用户名和密码 AJAX 检查
class UsernameCountView(View):
    # 用户名验证
    def get(self,request,username):
        # rules = '[a-zA-Z0-9]{5,20}'
        # if not re.match(rules,username):
        #     return JsonResponse({'code':0,'errmsg':'用户名格式错误'})
        count = User.objects.filter(username=username).count()
        return JsonResponse({'code':0,'count':count,'errmsg':'ok'})

class MobileCountView(View):
    # 手机号验证
    def get(self,request,mobile):
        count = User.objects.filter(mobile=mobile).count()
        return JsonResponse({'code':0,'count':count,'errmsg':'ok'})

# 注册
class RegisterView(View):
    def post(self,request):
        body_bytes = request.body
        body_dict = json.loads(body_bytes)
        print(type(body_dict),body_dict)

        username= body_dict.get('username')
        password= body_dict.get('password')
        password2= body_dict.get('password2')
        mobile = body_dict.get('mobile')
        image_code= body_dict.get('image_code')
        sms_code= body_dict.get('sms_code')
        allow= body_dict.get('allow')

        if not all([username,password,mobile]):
            return JsonResponse({'code':400,'errmsg':'缺少必要信息'})
        if not re.match(r'^[a-zA-Z0-9]{5,20}$',username):
            return JsonResponse({'code':400,'errmsg':'用户名格式错误'})
        if not re.match(r'^[a-zA-Z0-9_]{8,20}$',password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式错误'})
        if password != password2:
            return JsonResponse({'code': 400, 'errmsg': '两次密码不一致'})
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号格式错误'})
        if allow != True:
            return JsonResponse({'code': 400, 'errmsg': '未勾选同意协议'})
        # 验证码验证
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')
        redis_code = redis_cli.get(mobile).decode()
        if redis_code is None:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码失效'})
        if redis_code != sms_code:
            return JsonResponse({'code':400,'errmsg':'验证码错误'})

        # 保存的密码没有加密
        # User.objects.create(username = username,password = password,mobile = mobile)
        # 保存的密码加密
        try:
            user = User.objects.create_user(
                username = username,
                password = password,
                mobile = mobile
            )
        except Exception as e:
            print(e)
            return JsonResponse({'code': 400, 'errmsg': '注册失败'})

        # 保存账号,用户自动登录
        login(request,user)

        response = JsonResponse({'code':0,'errmsg':'ok'})
        response.set_cookie('username',username,max_age=3600 * 24 * 15)
        return response

# 登录
class LoginView(View):
    def post(self,request):
        data = json.loads(request.body)
        username = data.get('username')
        password = data.get('password')
        remembered = data.get('remembered')

        from django.contrib.auth import authenticate
        if not all([username,password]):
            return JsonResponse({'code':400,'errmsg':'缺少参数'})

        if re.match(r'1[3-9]\d{9}',username):
            User.USERNAME_FIELD = 'mobile'
        else:
            User.USERNAME_FIELD = 'username'

        user = authenticate(username = username,password = password)
        if user == None:
            return JsonResponse({'code':400,'errmsg':'用户名或密码错误'})

        # 记住账号密码
        if remembered:
            request.session.set_expiry(None)
        else:
            request.session.set_expiry(0)

        # session 状态保持
        from django.contrib.auth import login
        login(request,user)

        # 设置cookie
        response = JsonResponse({'code':0,'errmsg':'ok'})
        response.set_cookie('username',username,max_age = 3600 * 24 * 15)

        return response

# 退出登录
class LogoutView(View):
    def delete(self,request):
        logout(request)
        response = JsonResponse({'code':400,'errmsg':'ok'})
        response.delete_cookie('username')
        return response


# 用户中心管理权限逻辑
# from django.contrib.auth.mixins import LoginRequiredMixin

# 方法一 重写  LoginRequiredMixin 类的 dispatch 方法,缺点:只能用在用户中心,复用性差,如果要用在支付等其他地方,要重复写这段代码
# class LoginRequiredJSONMixin(LoginRequiredMixin):
#     def dispatch(self, request, *args, **kwargs):
#         if not request.user.is_authenticated:
#             return JsonResponse({'code':400,'errmsg':'未登录'})
#         return super().dispatch(request, *args, **kwargs)
# class CenterView(LoginRequiredJSONMixin,View):
#     def get(self,request):
#         return JsonResponse({'code':0,'errmsg':'ok'})

# 方法二 重写 LoginRequiredMixin 类的 handle_no_permission 方法
# class LoginRequiredJSONMixin(LoginRequiredMixin):
#     def handle_no_permission(self):
#         return JsonResponse({'code':400,'errmsg':'账号未登录'})
#
# class CenterView(LoginRequiredJSONMixin,View):
#     def get(self,request):
#         return JsonResponse({'code':0,'errmsg':'ok'})

# 方法三 在 utils 文件夹新建一个 view.py 文件,新建类 LoginRequiredJSONMixin,重写 LoginRequiredMixin 类中的 handle_no_permission 方法
# 所有需要验证用户登录权限的类都可以导入 LoginRequiredJSONMixin 进行权限管理
from utils.views import LoginRequiredJSONMixin

class CenterView(LoginRequiredJSONMixin,View):
    def get(self,request):
        info_data = {
            'username' : request.user.username,
            'email' : request.user.email,
            'mobile' : request.user.mobile,
            'email_active':request.user.email_active
        }

        return JsonResponse({'code':0,'errmsg':'ok','info_data':info_data})

class EmailView(LoginRequiredJSONMixin,View):
    def put(self,request):
        json_dict = json.loads(request.body)
        email = json_dict.get('email')
        if not email:
            return JsonResponse({'code':400,'errmsg':'缺少email数据'})
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$',email):
            return JsonResponse({'code':400,'errmsg':'email格式错误'})

        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            print(e)
            return JsonResponse({'code':400,'errmsg':'添加email失败'})

        # 发送认证邮件
        from django.core.mail import send_mail
        '''
        subject: 邮件标题  
        message：邮件内容
        from_email：发件人 发件人邮箱需要进行特殊设置
        recipient_list：收件人 [列表类型]
        
        要到setting.py配置邮箱相关信息
        '''
        subject = '图灵商城激活邮件'
        from_email = '图灵商城<173126631@qq.com>'
        recipient_list = ['2863535704@qq.com']
        # 发普通信息用 message ,发包含链接的信息用 html_message
        message = ""

        from apps.users.utils import generic_email_verify_token
        # 发送验证邮件
        token = generic_email_verify_token(user_id = request.user.id)
        verify_url = 'http://127.0.0.1:8080/success_verify_email.html?token=%s' % token
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用图灵商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s<a></p>' % (email, verify_url, verify_url)

        # 因为发送邮件也是属于堵塞代码 所以使用celery进行异步发送
        # send_mail(
        #     subject = subject,
        #     message = message,
        #     from_email=from_email,
        #     recipient_list = recipient_list,
        #     html_message = html_message
        # )

        # 使用celery进行邮件发送
        from celery_tasks.email.tasks import celery_send_email

        celery_send_email.delay(
            subject=subject,
            message=message,
            from_email=from_email,
            recipient_list=recipient_list,
            html_message=html_message
        )

        return JsonResponse({'code':0,'errmsg':'ok'})

# 邮箱状态验证

class EmailVerifyView(View):
    # 加密
    def put(self,request):
        parmas = request.GET
        token = parmas.get('token')
        if token is None:
            return JsonResponse({'code':400,'errmsg':'参数缺失'})

        # 解密
        from apps.users.utils import check_verify_token
        user_id = check_verify_token(token)
        if user_id is None:
            return JsonResponse({'code0':400,'errmsg':'参数错误'})
        user = User.objects.filter(id=user_id).first()
        user.email_active = True
        user.save()

        return JsonResponse({'code':0,'errmsg':'ok'})

'''
新增地址
    1. 接收前端传送过来的请求 接收数据
    2. 验证数据
    3. 数据入库
    4. 返回响应
'''
# from apps.users.models.User.DoesNotExist
class AddressCreateView(LoginRequiredJSONMixin,View):
    def post(self,request):
        user = request.user
        data = json.loads(request.body)
        receiver= data.get('receiver')
        province_id= data.get('province_id')
        city_id= data.get('city_id')
        district_id= data.get('district_id')
        place= data.get('place')
        mobile= data.get('mobile')
        tel= data.get('tel')
        email= data.get('email')
        if not all([receiver,province_id,city_id,district_id,place,mobile]):
            return JsonResponse({'code':400,'errmsg':'缺少参数'})
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return JsonResponse({'code':400,'errmsg':'手机格式错误'})
        if tel:
            if re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$',tel):
                return JsonResponse({'code':400,'errmsg':'电话格式错误'})
        if email:
            if re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$'):
                return JsonResponse({'code':400,'errmsg':'邮箱格式错误'})
        # 保存地址信息
        try:
            address = Address.objects.create(
                user = request.user,
                title = receiver,
                receiver = receiver,
                province_id = province_id,
                city_id = city_id,
                district_id = district_id,
                place = place,
                mobile = mobile,
                tel = tel,
                email = email
            )
        except Exception as e:
            print(e)
            return JsonResponse({'code':400,'errmsg':'保存地址出错'})
        # 返回地址
        address_dict = {
            'id': address.id,
            'title': address.title,
            'receiver': address.receiver,
            'province': address.province.name,
            'city' : address.city.name,
            'district': address.district.name,
            'place': address.place,
            'mobile': address.mobile,
            'tel': address.tel,
            'email': address.email
        }

        return JsonResponse({'code':0,'errmsg':'ok','address':address_dict})

# 获取登录用户的所有地址
class ShowAddress(LoginRequiredJSONMixin,View):
    def get(self,request):
        # 获取登录用户的所有地址
        addresses = Address.objects.filter(user=request.user,is_deleted=False)
        address_dict_list =[]
        for address in addresses:
            address_dict_list.append(
                {
                    'id': address.id,
                    'title': address.title,
                    'receiver': address.receiver,
                    'province': address.province.name,
                    'city' : address.city.name,
                    'district': address.district.name,
                    'place': address.place,
                    'mobile': address.mobile,
                    'tel': address.tel,
                    'email': address.email
                }
            )

        return JsonResponse({'code':0,'errmsg':'ok','addresses':address_dict_list})

# 更新地址
class UpdateAddressView(LoginRequiredJSONMixin,View):
    def put(self,request,address_id):
        json_dict = json.loads(request.body)
        #接收信息
        receiver= json_dict.get('receiver')
        province_id= json_dict.get('province_id')
        city_id= json_dict.get('city_id')
        district_id= json_dict.get('district_id')
        place= json_dict.get('place')
        mobile= json_dict.get('mobile')
        tel= json_dict.get('tel')
        email= json_dict.get('email')

        # 校验信息
        if not all([receiver,province_id,city_id,district_id,place,mobile]):
            return JsonResponse({'code':400,'errmsg':'缺少参数'})
        if not re.match(r'^1[3-9]\d{9}$',mobile):
            return JsonResponse({'code':400,'errmsg':'手机格式错误'})
        if tel:
            if re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$',tel):
                return JsonResponse({'code':400,'errmsg':'电话格式错误'})
        if email:
            if re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$'):
                return JsonResponse({'code':400,'errmsg':'邮箱格式错误'})
        # 更新信息
        try:
            Address.objects.filter(id=address_id).update(
                user = request.user,
                title = receiver,
                receiver = receiver,
                province_id = province_id,
                city_id = city_id,
                district_id = district_id,
                place = place,
                mobile = mobile,
                tel = tel,
                email = email
            )
        except Exception as e:
            print(e)
            return JsonResponse({'code':400,'errmsg':'更新地址错误'})
        # 构造信息
        address = Address.objects.get(id=address_id)
        address_dict = {
            'id': address.id,
            'title': address.title,
            'receiver': address.receiver,
            'province': address.province.name,
            'city' : address.city.name,
            'district': address.district.name,
            'place': address.place,
            'mobile': address.mobile,
            'tel': address.tel,
            'email': address.email
        }
        return JsonResponse({'code':0,'errmsg':'ok','address':address_dict})

    # 删除地址
    def delete(self,request,address_id):
        address = Address.objects.filter(id=address_id).first()
        try:
            address.is_deleted = True
            address.save()
        except  Exception as e:
            print(e)
            return JsonResponse({'code':400,'errmsg':'删除地址失败'})
        return JsonResponse({'code':0,'errmsg':'ok'})

# 恢复删除的地址
class RecoverAddressView(LoginRequiredJSONMixin,View):
    def get (self,request):
        addresses = Address.objects.filter(user=request.user,is_deleted = True)
        for address in addresses:
            try:
                address.is_deleted = False
                address.save()
            except Exception as e:
                print(e)
                return JsonResponse({'code':400,'errmsg':'恢复地址失败'})

        return JsonResponse({'code':0,'errmsg':'ok'})






